package com.globefrog.common.util;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;

/**
 * @Author: caijinbang
 * @Description:
 * @Date: Create in 2021-03-06
 */
public class ObjectMapperBuilder {

  static final ObjectMapper DEFAULT_OBJECT_MAPPER = createMapper();
  static final ObjectMapperBuilder DEFAULT_OBJECT_MAPPER_BUILDER = new ObjectMapperBuilder();
  private final ObjectMapper objectMapper;

  public ObjectMapperBuilder() {
    this(DEFAULT_OBJECT_MAPPER);
  }

  public ObjectMapperBuilder(ObjectMapper mapper) {
    this.objectMapper = mapper;
  }

  public ObjectMapper get() {
    return this.objectMapper;
  }

  public static ObjectMapperBuilder defaultObjectMapper() {
    return DEFAULT_OBJECT_MAPPER_BUILDER;
  }

  public static ObjectMapper getObjectMapper() {
    return DEFAULT_OBJECT_MAPPER;
  }

  private static ObjectMapper createMapper() {
    ObjectMapper mapper = new ObjectMapper();
    AnnotationIntrospector primary = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
    AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
    mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(primary, secondary));
    mapper.setSerializationInclusion(Include.NON_NULL);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME, true);
    mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
    return mapper;
  }
}
